'''
Created on 14/04/2013

@author: victor,cristian,jean
'''
from . import jsonifiedview
from .LoginViews import islogged
from flask import Flask, session, redirect, url_for, escape, request, Response
from pm import app
from pm.database import db
from pm.models.Proyectos import Proyectos
from pm.models.Usuarios import Usuarios
from pm.models.UsuariosRoles import UsuariosRoles
from pm.models.UsuariosRolesFases import UsuariosRolesFases
from pm.views import ensureParams
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm.exc import NoResultFound
import simplejson
from pm.models.MiembrosComite import MiembrosComite 
from pm.models.SolicitudCambio import SolicitudCambio

@app.route('/usuario/listar', methods=['GET', 'POST']) 
@jsonifiedview
def listarUsuarios():
    '''
    Lista los usuarios existentes en el sistema
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    
    users = Usuarios.query
    users = users.filter(Usuarios.nombre.like('%' + params['nombre'] + '%')) if 'nombre' in params else users
    users = users.filter(Usuarios.apellido.like('%' + params['apellido'] + '%')) if 'apellido' in params else users 
    users = users.filter(Usuarios.telefono.like('%' + params['telefono'] + '%')) if 'telefono' in params else users 
    users = users.filter(Usuarios.direccion.like('%' + params['direccion'] + '%')) if 'direccion' in params else users 
    users = users.filter(Usuarios.user_name.like('%' + params['user_name'] + '%')) if 'user_name' in params else users       
    return users.order_by(Usuarios.id_usuario).all()

@app.route('/usuario/crear', methods=['GET', 'POST']) 
@jsonifiedview
def crearUsuario():
    '''
        Crea un nuevo usuario

    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response ={}
  
    
    
    if not ensureParams(params,['nombre','apellido', 'direccion', 'user_name', 'password','correo','activo','telefono','cedula']): 
        response ={"success" : False , "msg" : "Parametros Insuficientes"} 
        return response   
             
    try:
        usuario = Usuarios(params['user_name'],params['password'],params['nombre'],params['apellido'],params['direccion'],params['telefono'],params['correo'],params['activo'], params['cedula'])
        db.session.add(usuario)
        db.session.commit()
        response ={"success" : True , "msg" : "Creacion Exitosa"}
        return response
    except IntegrityError:
        response ={"success" : False , "msg" : "Usuario ya existe"} 
        return response
    except Exception, e:
        db.session.rollback()
        response ={"success" : False , "msg" : "Error en la base de datos"}
        return response 
    
@app.route('/usuario/modificar', methods=['GET', 'POST']) 
@jsonifiedview
def modificarUsuario():
    '''
        Modifica un usuario creado
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response ={}
    
    if not ensureParams(params,['nombre','apellido', 'direccion','correo','activo','telefono','cedula']): 
        response ={"success" : False , "msg" : "Parametros Insuficientes"} 
        return response   
          
    try:
        user =  Usuarios.query.filter(Usuarios.id_usuario == params['id']).first()
        if params['activo'] != user.activo:
            solicitudCambio = SolicitudCambio.query.filter(SolicitudCambio.id_usuario == user.id_usuario).filter(SolicitudCambio.estado == 'En Votacion').first()
            if solicitudCambio:
                response ={"success" : False , "msg" : "El usuario no puede ser desactivado ya que tiene una solictud en votacion"} 
                return response
            miembroComite = MiembrosComite.query.filter(MiembrosComite.id_usuario == params['id']).first()
            if miembroComite!= None:
                response ={"success" : False , "msg" : "El usuario no puede ser desactivado ya que pertenece a un comite"} 
                return response
        usuario = Usuarios.query.filter(Usuarios.id_usuario == params['id']).update({'nombre':params['nombre'],
        'apellido':params['apellido'],'telefono':params['telefono'],'direccion':params['direccion'],
        'correo':params['correo'],'activo':params['activo'],'cedula':params['cedula']})
        db.session.commit()
        response ={"success" : True , "msg" : "Actualizacion exitosa"}
        return response
    except Exception, e:
        db.session.rollback()
        response ={"success" : False , "msg" : "Error en la base de datos" }
        return response 
    
@app.route('/usuario/asignarusuarioaproyecto', methods=['GET', 'POST']) 
@jsonifiedview
def asignarUsuarioAProyecto():
    '''
       Asigna un usuario a un proyecto creado
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response ={}
    
    if not ensureParams(params,['id_usuario','id_proyecto', 'lista_roles']): 
        response ={"success" : False , "msg" : "Parametros Insuficientes"} 
        return response
    try:
        identificadores= simplejson.loads(params['lista_roles'])
        for i in identificadores:
            if i ==1:
                response ={"success" : False , "msg" : "El rol de administrador no puede ser asignado a un proyecto"} 
                return response
            
            usuarioRol = UsuariosRoles.query.filter(UsuariosRoles.id_rol == i).filter(UsuariosRoles.id_usuario == params['id_usuario']).one()
            usuarioRolFase = UsuariosRolesFases(usuarioRol.id_usuario_rol, None, params['id_proyecto'], True, None)
            db.session.add(usuarioRolFase)
            db.session.commit()
        response ={"success" : True , "msg" : "Asignacion exitosa"}
        return response
    except Exception, e:
        response ={"success" : False , "msg" : "Ups, ha ocurrido un error"}
        return response


@app.route('/usuario/listarproyectosbyusuario', methods=['GET', 'POST']) 
@jsonifiedview
def listarProyectosByUsuario():
    '''
        Listar proyectos que tiene un determinado usuario
        @param id: identificador del usuario
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    resp = []
    
    
    
    if not ensureParams(params, ['id']): 
       
        return resp
    
    usuariosRoles = UsuariosRoles.query.filter(UsuariosRoles.id_usuario == params['id']).all()
    for ur in usuariosRoles:
        usuariosRolesFases = UsuariosRolesFases.query.filter(UsuariosRolesFases.id_usuario_rol == ur.id_usuario_rol).filter(UsuariosRolesFases.activo==True).all()
        for urf in usuariosRolesFases:
            proyec = Proyectos.query.filter(Proyectos.id_proyecto == urf.id_proyecto).one()
            if proyec not in resp:
                if proyec.activo==True:
                    resp.append(proyec)
                
    return resp

@app.route('/usuario/listarposiblesusuariosporproyecto', methods=['GET', 'POST']) 
@jsonifiedview
def listarPosiblesUsuariosPorProyecto():
    '''
        Lista los usuarios que no estan asociados a un proyecto
        @param id_proyecto:  id del proyecto al que se quiere asignar un proyecto
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    roleUsu = []
    resp= []
    
    if not ensureParams(params,['id_proyecto']): 
        return resp
    usuarioRoles = UsuariosRoles.query.filter(UsuariosRoles.activo== True).all()
    for ur in usuarioRoles:
        roleUsu.append(ur)
    #listamos los registros de usuarios roles que no estan asociados a ese proyecto
    usuariosRolesFases = UsuariosRolesFases.query.filter(UsuariosRolesFases.id_proyecto == params['id_proyecto']).all()
    for urf in usuariosRolesFases:
        urAux = UsuariosRoles.query.filter(UsuariosRoles.id_usuario_rol == urf.id_usuario_rol).one()
        roleUsu.remove(urAux)
    for ru in roleUsu:
        usuario = Usuarios.query.filter(Usuarios.id_usuario == ru.id_usuario).one()
        if usuario not in resp:
            resp.append(usuario)
        for r in resp:
            band = False
            urAux = UsuariosRoles.query.filter(UsuariosRoles.id_usuario ==r.id_usuario).all()
            for uRolAux in urAux:
                if uRolAux.id_rol != 1 and uRolAux.id_rol != 2:
                    band = True
            if band == False:
                resp.remove(r)        
    return resp

@app.route('/usuario/listarposiblesusuariosporfase', methods=['GET', 'POST']) 
@jsonifiedview
def listarPosiblesUsuariosPorFase():
    '''
        Lista los usuarios que no estan asociados a una fase
        @param id_proyecto:  id del proyecto al que se quiere asignar un proyecto
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    roleUsu = []
    resp= []
    
    if not ensureParams(params,['id_proyecto','id_fase']): 
        return resp
    id_proyecto= int(str(params['id_proyecto']))
    id_fase= int(str(params['id_fase']))
    
    usuarioRoles = UsuariosRoles.query.filter(UsuariosRoles.id_rol != 1).filter(UsuariosRoles.id_rol != 2).filter(UsuariosRoles.activo== True).all()
    usuariosRolesxPr = UsuariosRolesFases.query.filter(UsuariosRolesFases.id_proyecto == id_proyecto).all()
    for ur in usuarioRoles:
        for urf in usuariosRolesxPr:
            if urf.id_usuario_rol == ur.id_usuario_rol:
                if ur not in roleUsu:
                    roleUsu.append(ur)
             
    #listamos los registros de usuarios roles que no estan asociados a ese proyecto
    usuariosRolesFases = UsuariosRolesFases.query.filter(UsuariosRolesFases.id_proyecto == id_proyecto).filter(UsuariosRolesFases.id_fase==id_fase).all()
    for urf in usuariosRolesFases:
        urAux = UsuariosRoles.query.filter(UsuariosRoles.id_usuario_rol == urf.id_usuario_rol).one()
        roleUsu.remove(urAux)
    for ru in roleUsu:
        usuario = Usuarios.query.filter(Usuarios.id_usuario == ru.id_usuario).one()
        if usuario not in resp:
            resp.append(usuario)      
    return resp

@app.route('/usuario/listarusuariosbyfase', methods=['GET', 'POST']) 
@jsonifiedview
def listarUsuariosByFase():
    '''
        Lista los usuarios que pertenecen a una fase dada
        @param id_fase:  id del proyecto al que se quiere asignar un proyecto
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    resp= []
    
    if not ensureParams(params,['id_fase']): 
        return resp
    
    usuariosRolesFases = UsuariosRolesFases.query.filter(UsuariosRolesFases.id_fase == params['id_fase']).all()
    for ur in usuariosRolesFases:
        usuariosRoles = UsuariosRoles.query.filter(UsuariosRoles.id_usuario_rol == ur.id_usuario_rol).one()
        usuarios = Usuarios.query.filter(Usuarios.id_usuario == usuariosRoles.id_usuario).one()
        if usuarios not in resp:
            resp.append(usuarios)
            
    return resp